﻿using Microsoft.Extensions.Options;
using System.Security.Claims;

namespace ProxyServer.Acme;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddAcme(this IServiceCollection services)
    {
        services.AddTransient<IConfigureOptions<FileSystemAcmeStoreOptions>>(sp =>
        {
            var section = sp.GetService<IConfiguration>()?.GetSection("AcmeStore");
            return new ConfigureOptions<FileSystemAcmeStoreOptions>(options => section?.Bind(options));
        });
        services.AddTransient<IConfigureOptions<AcmeOptions>>(sp =>
        {
            var section = sp.GetService<IConfiguration>()?.GetSection("Acme");
            var env = sp.GetService<IHostEnvironment>();
            
            return new ConfigureOptions<AcmeOptions>(options =>
            {
                section?.Bind(options);
                if (env?.IsProduction() ?? false)
                {
                    options.CaName = AcmeStoreConstants.CaNames.LetsEncrypt;
                }
            });
        });

        services.AddScoped<DeveloperCertLoader>();
        services.AddScoped<AcmeStateMachineContext>();
        services.AddTransient<TerminalState>();
        services.AddTransient<CheckForAcmeAccountState>();

        services.AddTransient<BeginServiceCertificateState>();
        services.AddTransient<CreateServiceCertificateOrderState>();
        services.AddTransient<ExportServiceCertificateOrderState>();
        services.AddTransient<ChallengeServiceOrderState>();
        services.AddTransient<FinalizeServiceOrderState>();

        services.AddOptions<ServiceAcmeOptions>();
        
        services.AddScoped<IAcmeStore, FileSystemAcmeStore>();
        services.AddScoped<AcmeClientFactory>();
        
        services.AddSingleton<ICertificateRepository, FileSystemCertificateRepository>();

        services.AddHttpClient(AcmeStoreConstants.CaNames.LetsEncryptStaging, c =>
        {
            c.BaseAddress = new Uri(AcmeStoreConstants.CaUrls.LetsEncryptV2StagingEndpoint);
        })
        .ConfigurePrimaryHttpMessageHandler(() =>
        {
            return new HttpClientHandler
            {
                //ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
                //AllowAutoRedirect = false,
                CheckCertificateRevocationList = false
            };
        })
        ;
        services.AddHttpClient(AcmeStoreConstants.CaNames.LetsEncrypt, c =>
        {
            c.BaseAddress = new Uri(AcmeStoreConstants.CaUrls.LetsEncryptV2Endpoint);
        })
        .ConfigurePrimaryHttpMessageHandler(() =>
        {
            return new HttpClientHandler
            {
                //ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
                //AllowAutoRedirect = false,
                CheckCertificateRevocationList = false,
            };
        })
        ;
        return services;
    }
}
